package cn.mw.cmdb.processor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.mw.cmdb.entity.InstanceInfoExtend;
import cn.mw.cmdb.entity.ModelSystemTreeViewInfo;
import cn.mw.cmdb.param.InstanceSearchParam;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.util.AssetsTool;
import cn.mw.microMonitorCommon.api.cmdb.TableIdEnum;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import com.google.common.base.Strings;
import org.apache.commons.collections4.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

import static cn.mw.cmdb.entity.PropertyType.relationIdKey;
import static cn.mw.cmdb.entity.PropertyType.relationNameKey;
import static cn.mw.cmdb.util.ValConvertUtil.intValueConvert;
import static cn.mw.cmdb.util.ValConvertUtil.strValueConvert;

public class TreeProcessorBusiness implements TreeProccessorTable {
    private static final String noGroupName = "未分组";
    private static final String noModelSystemId = "modelSystemId";

    private static final String noModelClassifyId = "modelClassifyId";

    public static final String modelSystemPid = "0";

    public static final String modelSystem = "modelSystem";

    public static final String modelClassify = "modelClassify";

    private CmdbServiceManage cmdbServiceManage;

    public TreeProcessorBusiness(CmdbServiceManage cmdbServiceManage) {
        this.cmdbServiceManage = cmdbServiceManage;
    }

    @Override
    public List genTreeData(TableDataProcessorContext context) throws Exception {
        List<TreeView> ret = new ArrayList<>();
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);

        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        BeanUtil.copyProperties(context.getTableSearchParam(), instanceSearchParam, CopyOptions.create().setIgnoreNullValue(true));

        List<InstanceInfoExtend> list = instanceService.aggregateList(instanceSearchParam);
        List<ModelSystemTreeViewInfo> modelSystemList = new ArrayList<>();
        Map<String, List<InstanceInfoExtend>> modelTreePathMap = new HashMap<>();

        ModelSystemTreeViewInfo modelSystemTreeViewInfo = new ModelSystemTreeViewInfo();
        modelSystemTreeViewInfo.setId(modelSystemPid);
        modelSystemTreeViewInfo.setItemName(TableIdEnum.business.getName());
        modelSystemTreeViewInfo.setType(TableIdEnum.business.name());
        modelSystemList.add(modelSystemTreeViewInfo);
        //判断是否有业务分类下级
        boolean modelClassifyFlag = list.stream().anyMatch(s -> s.getData() != null && s.getData().get(modelClassify) != null);

        if (CollectionUtils.isNotEmpty(list)) {
            getRelationTreeInfo(modelClassifyFlag, modelSystemList, modelTreePathMap, list,"", modelSystem, modelSystemPid);
        }
        ret.addAll(modelSystemList);
        int sumCount = 0;
        for (TreeView treeView : ret) {
            String treePath = strValueConvert(treeView.getTreePath());
            if (modelTreePathMap != null && modelTreePathMap.containsKey(treePath)) {
                if(modelSystem.equals(treeView.getType())){
                    sumCount += intValueConvert(modelTreePathMap.get(treePath).size());
                }
                treeView.setCount(intValueConvert(modelTreePathMap.get(treePath).size()));
                treeView.setItemAssetsStatus(AssetsTool.calcItemAssetsStatus(modelTreePathMap.get(treePath), treeView));
            }
        }
        //设置更节点的统计
        for (TreeView treeView : ret) {
            if (TableIdEnum.business.name().equals(treeView.getType())) {
                treeView.setCount(sumCount);
            }
        }
        List<TreeView> sortList = ret.stream().sorted(Comparator.comparing(TreeView::getItemName)).collect(Collectors.toList());
        return sortList;
    }

    public void getRelationTreeInfo(Boolean modelClassifyFlag, List<ModelSystemTreeViewInfo> modelSystemList, Map<String, List<InstanceInfoExtend>> modelTreePathMap,
                                    List<InstanceInfoExtend> list, String path, String relationType, Object pId) {
        Map<Object, List<InstanceInfoExtend>> modelSystemMap = list.stream().filter(s -> s.getData() != null && s.getData().get(relationType) != null).collect(Collectors.groupingBy(s -> s.getData().get(relationType)));

        for (Map.Entry<Object, List<InstanceInfoExtend>> entry : modelSystemMap.entrySet()) {
            Object k = entry.getKey();
            List<InstanceInfoExtend> v = entry.getValue();
            ModelSystemTreeViewInfo modelSystemInfo = new ModelSystemTreeViewInfo();
            if (k instanceof Map) {
                List<InstanceInfoExtend> modelSystemInfoList = v;
                Map<String, Object> relationSystemMap = (Map) k;
                Object id = relationSystemMap.get(relationIdKey);
                modelSystemInfo.setItemName(strValueConvert(relationSystemMap.get(relationNameKey)));
                modelSystemInfo.setParentId(pId);
                if (Strings.isNullOrEmpty(path)) {
                    modelSystemInfo.setTreePath(strValueConvert(id));
                } else {
                    modelSystemInfo.setTreePath(path + "," + id);
                }
                modelSystemInfo.setId(modelSystemInfo.getTreePath());
                modelSystemInfo.setType(relationType);
                modelSystemList.add(modelSystemInfo);
                modelTreePathMap.put(strValueConvert(modelSystemInfo.getTreePath()), v);
                if (modelClassifyFlag) {
                    getRelationTreeInfo(false, modelSystemList, modelTreePathMap, modelSystemInfoList,modelSystemInfo.getTreePath(), modelClassify, modelSystemInfo.getId());
                }
            }
        }
    }
}
